{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "36549e5f",
   "metadata": {},
   "source": [
    "## 知识点\n",
    "1. Counter()初始化生成一个dict，每个元素是key，元素出现的次数是value\n",
    "2. Counter.most_common(n) 永远只会返回第一个value最大的item\n",
    "3. Counter本身是一个dict，在python3.6以后这个dict是内部排序的\n",
    "2. dict 中的每一个元素属于dict.items()，如果单独寻找key使用dict.keys()，如果单独寻找value使用dict.values()\n",
    "3. with open(file_path, module='rwf') as f: for line in f:\n",
    "4. python 内置字符串处理函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "f6d45642",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "key:  \\  value:  4751\n",
      "key:  r  value:  2408\n",
      "key:  t  value:  2078\n",
      "key:  f  value:  1324\n",
      "key:     value:  6378\n",
      "key:  a  value:  2339\n",
      "key:  n  value:  1606\n",
      "key:  s  value:  1635\n",
      "key:  i  value:  2530\n",
      "key:  c  value:  2132\n",
      "key:  p  value:  1187\n",
      "key:  0  value:  1401\n",
      "key:  d  value:  1827\n",
      "key:  e  value:  1824\n",
      "key:  h  value:  2317\n",
      "key:  l  value:  2588\n",
      "key:  o  value:  1402\n"
     ]
    }
   ],
   "source": [
    "from collections import Counter\n",
    "import os\n",
    "\n",
    "# print(os.path.abspath(''))\n",
    "f_path = './counter-test.doc'\n",
    "\n",
    "c = Counter()\n",
    "thresholds = 1000\n",
    "\n",
    "with open(f_path,'r') as f:\n",
    "    for line in f:\n",
    "        c.update(line.rstrip().lower())\n",
    "\n",
    "for key, value in c.items() :\n",
    "    if(value>thresholds):\n",
    "        print(\"key: \", key, \" value: \", value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "c47b848a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(' ', 6378)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c.most_common(1)[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "094a9ddd",
   "metadata": {},
   "source": [
    "## knn 简单编程\n",
    "1. 假设数据的格式\n",
    "    > data = [data_x, data_y] <br>\n",
    "    > label = [label] <br>\n",
    "2. knn判断过程\n",
    "    > 1. 找到最近的k个点 <br>\n",
    "    > 2. 在这k个点中选举出数量最多的标签 <br>\n",
    "    > 3. 如果标签一样多，扩大k值，直到选出绝对多数 <br>\n",
    "    > 4. 如果用尽所有点绝对多数有持平，那么选择标签最小的 <br>\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21089b2f",
   "metadata": {},
   "source": [
    "### find_max"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7750c643",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from matplotlib import pyplot\n",
    "from collections import Counter\n",
    "\n",
    "def find_max(label):\n",
    "    '''\n",
    "    input: []; k nearest labels\n",
    "    output: []; maximum label\n",
    "    '''\n",
    "    m_label = []\n",
    "    \n",
    "    c_label = Counter(label)\n",
    "    # find max value of current labels, could be more than one label\n",
    "    l_max=max(c_label.values())\n",
    "    for key, value in c_label.items():\n",
    "        if value == l_max:\n",
    "            m_label.append(key)\n",
    "        else:\n",
    "            continue\n",
    "    return m_label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "6e3fb660",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 2, 0]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# test of find_max\n",
    "data = []\n",
    "label = [3,3,3,5,5,7,7,7,7,7,2,2,2,2,2,0,0,0,0,0]\n",
    "find_max(data,label)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "924baf94",
   "metadata": {},
   "source": [
    "### distance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "6840049d",
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "\n",
    "def distance(d0, d1):\n",
    "    '''\n",
    "    calculate distance between two data points\n",
    "    \n",
    "    input: 2d tuple & 2d tuple; two tuples\n",
    "    output: one number; distance\n",
    "    '''\n",
    "    return sqrt(np.sum((d0-d1)*(d0-d1),axis=0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f1f86e18",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.099999835444429"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# test of distance\n",
    "d0 = np.asarray((2.4, 5.1),dtype=np.float32)\n",
    "d1 = np.asarray((6.9, 2.7),dtype=np.float32)\n",
    "distance(d0,d1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "516e72d6",
   "metadata": {},
   "source": [
    "### pop_over_dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb6a4f84",
   "metadata": {},
   "outputs": [],
   "source": [
    "# customize one pop function\n",
    "\n",
    "def pop_over_dist(l, max):\n",
    "    '''\n",
    "    pop item according to setting value \n",
    "    input: list and setting value\n",
    "    output: popped item\n",
    "    function pop out item from given list\n",
    "    '''\n",
    "    popped = (0,0,0)\n",
    "    for idx,(a,b,c) in enumerate(l):\n",
    "        if b == max:\n",
    "            popped = l.pop(idx)\n",
    "    return popped"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "id": "1f02e8a7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(2, 3, 4), (5, 4, 6), (7, 3, 1)]\n"
     ]
    }
   ],
   "source": [
    "l = [(2, 3, 4), (5, 4, 6), (7, 3, 1), (6, 10, 12)]\n",
    "pop_over_dist(l, 10)\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "372ce837",
   "metadata": {},
   "source": [
    "### find_maximum_dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6a539738",
   "metadata": {},
   "outputs": [],
   "source": [
    "# find maximum distance in cluster\n",
    "\n",
    "def find_maximum_dist(l):\n",
    "    '''\n",
    "    find maximum distance over cluster\n",
    "    input: list \n",
    "    output: maximum distance\n",
    "    '''\n",
    "    max_dist = 0\n",
    "    for (dat,dist,idx) in l:\n",
    "        if dist >= max_dist:\n",
    "            max_dist = dist\n",
    "    return max_dist    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "36f32cc5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# test find_maximum_dist\n",
    "\n",
    "find_maximum_dist(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a64896f1",
   "metadata": {},
   "source": [
    "### find_k_nearest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "d781bce8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_k_nearest(data, pt, k):\n",
    "    '''\n",
    "    input: data, point for classification, k for number of classes\n",
    "    output: k nearest point\n",
    "    '''\n",
    "    # list storing k-nearest points and its corresponding idx\n",
    "    # this k_nearest should be a tuple list: (data,distance,idx)\n",
    "    k_nearest = []\n",
    "    # first put k points into cluster, sort cluster\n",
    "    # then find the maximum distance of these k point\n",
    "    # if new distance is smaller than the maximum, pop the maximum-distance point and put in this new point\n",
    "    # the number of members of this cluster is always k\n",
    "    k_maximum_dis = 0\n",
    "    for (idx,pts) in enumerate(data):\n",
    "        # first put k points into cluster\n",
    "        dist = distance(pts, pt)\n",
    "        # print(\"this distance is: \", dist)\n",
    "        if idx < k:          \n",
    "            k_nearest.append((pts,dist,idx))\n",
    "            # find the maximum distance of this cluster\n",
    "            k_maximum_dis = find_maximum_dist(k_nearest)\n",
    "        else:\n",
    "            # put in points that is smaller than the maximum distance \n",
    "            # then pop out points with maximum distance\n",
    "            # one exception: if they are of the same distance, keep both\n",
    "            if dist < k_maximum_dis:\n",
    "                pop_over_dist(k_nearest, k_maximum_dis)\n",
    "                k_nearest.append((pts, dist, idx))\n",
    "                k_maximum_dis = find_maximum_dist(k_nearest)\n",
    "            elif dist == k_maximum_dis:\n",
    "                k_nearest.append((pts, dist, idx))\n",
    "            else:\n",
    "                continue\n",
    "    return k_nearest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "9fd0cb58",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(array([1.70575908, 4.30614891]), 2.6445003972655443, 9),\n",
       " (array([ 2.38280076, -1.54101043]), 3.5943969944164653, 38),\n",
       " (array([0.51791173, 5.40115406]), 4.210535730363436, 40),\n",
       " (array([ 5.44236549, -2.18812716]), 4.848253116293, 46),\n",
       " (array([3.06536602, 4.98375305]), 2.9844689590869953, 47)]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sigma = 10\n",
    "miu = 5\n",
    "data = (sigma * np.random.randn(100,)+ miu).reshape(50,2)\n",
    "target = np.asarray((3,2),dtype=np.float32)\n",
    "find_k_nearest(data, target, 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ba54135",
   "metadata": {},
   "source": [
    "### vote"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "0c181fbb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# vote maximum label\n",
    "\n",
    "def vote(data, label, target, k):\n",
    "    '''\n",
    "    find which cluster this new point should belong\n",
    "    using voting\n",
    "    input: \n",
    "        data -> labelled points\n",
    "        label -> labels of points\n",
    "        point -> target point waiting for classification  \n",
    "        k -> number of nearest points\n",
    "    output: class\n",
    "    '''\n",
    "    # label_list containing corresponding label via the same index between data and label\n",
    "    label_list = []\n",
    "    # pts is 3d tuple (point, distance, index)\n",
    "    pts = find_k_nearest(data, target , k)\n",
    "    for (_,_,idx) in pts:\n",
    "        label_list.append(label[idx])\n",
    "    # find maximum number of label\n",
    "    max_label = find_max(label_list)\n",
    "    # if we have more than one maximum number of label\n",
    "    if len(max_label) >= 2 and k<= len(data)/2:\n",
    "        vote(data, label, target, k+1)\n",
    "    else:\n",
    "        return max_label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "id": "f5a0850c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate lable with some dumb methods\n",
    "def label_gen_func(shape,k):\n",
    "    '''\n",
    "    generate k-class label\n",
    "    input: \n",
    "        shape -> shape of label list\n",
    "        k -> k classes\n",
    "    output: label list\n",
    "    '''\n",
    "    label = []\n",
    "    raw_num = np.random.randint(0,100,shape).tolist()\n",
    "    for idx,num in enumerate(raw_num):\n",
    "        for i in range(k):\n",
    "            if num <= (i+1) * 100/k:\n",
    "                label.append(i)\n",
    "                raw_num[idx] = 1000\n",
    "                break\n",
    "    return label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "id": "d0806df2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 0, 2, 4, 4, 3, 2, 3, 3, 2, 2, 1, 1, 4, 3, 3, 1, 0, 1, 3, 0, 4, 0, 3, 4, 4, 4, 4, 1, 3, 4, 0, 3, 1, 0, 0, 3, 4, 2, 3, 2, 2, 2, 3, 1, 3, 2, 4, 3, 1]\n",
      "50\n"
     ]
    }
   ],
   "source": [
    "res = label_gen_func(50,5)\n",
    "print(res)\n",
    "print(len(res))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 239,
   "id": "2a9fe4f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0]\n"
     ]
    }
   ],
   "source": [
    "# final test with small number of data\n",
    "k = 5\n",
    "sigma = 10\n",
    "miu = 5\n",
    "data = (sigma * np.random.randn(100,)+ miu).reshape(50,2)\n",
    "label = label_gen_func(50,5)\n",
    "target = np.asarray((3,2),dtype=np.float32)\n",
    "target_lab = vote(data, label, target, k)\n",
    "print(target_lab)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eeb27677",
   "metadata": {},
   "source": [
    "### visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "id": "3eb34e9b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyQAAAJzCAYAAAD+9tf/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAABJ0AAASdAHeZh94AACAKUlEQVR4nO3de1xUdf7H8fcwgOFAmjfwQuIFy0viJTQDUdRSyy62ldrmZf2ptWpplulqd8tbtaWtu2tZ3tcs13S7rNlqWOAlbBXzUgkuLrUKKaWCiDDM74+J0VFU0DNzZuD1fDx4TPM9Z2Y+82Ea58053+9Y8vPzHQIAAAAAEwSYXQAAAACAqotAAgAAAMA0BBIAAAAApiGQAAAAADANgQQAAACAaQgkAAAAAExDIAEAAABgGgIJAAAAANMQSAAAAACYhkACAAAAwDQEEgAAAACmIZAAgBe0bNlSffr0MbsMQ9lsNo0aNeqK7qMy9gUAUDGBZhcAAPBPCxYsUNOmTS+6z5/+9CfVqFFDgwcP9lJVAAB/QyABAFyWQYMGXXKfefPmqXHjxgQSAMAFccoWAAAAANMQSADABCdOnFBiYqKuvfZa7dq1yzVeOqfi0KFDeuCBB1S/fn1FRUXpiSeeUFFRUYX3K4/OnTsrPj5ekvTjjz/KZrMpISFBkpSVlSWbzabp06efd7sLzSF56aWXZLPZZLPZ9N///ldffvml63rLli3LrMGI51Fq+fLluvHGG1W3bl3deOONWrx4sQYNGqRatWrpiy++OK9+u92uN954Q507d1aPHj3Ou79du3bpN7/5jcLDwxUREaEBAwZo3759bvv06dOnzOc2YMAAt3GbzaYRI0bomWeeUePGjVW7dm3169dP33zzzXm3Xb9+vXr16qWGDRuqQYMG6tOnjzZv3nxZPQEAX0YgAQAvy8/P129+8xtlZGToo48+Utu2bd22//LLL+rdu7cCAgL04osvKjo6Wn/5y1/017/+9bL2u5ROnTrpu+++U0lJieuD8d69e1VSUuL64H3jjTeW+/7uvPNOLViwQAsWLFCdOnV03XXXua7Pnj37vP2Neh6S9Mknn2jUqFGKiorSyy+/rPbt22v06NG6+uqrNW/ePDVr1sxt/5KSEt1///166aWXdP3116tXr15u27du3aoePXpo586devLJJ/X4449r27Zt6t69u3bs2FHh+iTpgw8+0IoVKzRhwgQ9/vjj+vrrr3XrrbcqMzPTtc/XX3+te++9V6dOndKzzz6r559/XgUFBbr77rv1ww8/XNbjAoCvYg4JAHhRQUGB7rvvPn377bdlhhFJ+uabbzR8+HC98cYbkqS7775bTZs2VVJSkh555JEK73cpsbGxeuedd3Tw4EHt3r1bffr00caNG5Wenq59+/bJYrEoNja23Pd3ww036IYbbpAkvfDCC6pXr95F55sY9TwkaePGjZKkhQsXKiwsTMOGDdO6dev0008/lVnD2rVr1apVK+3bt0/XXHPNedvHjh2rwMBAffnll2rQoIEk6d5771VsbKzGjRvndsSlvIqLi/XJJ58oOjpaktShQwf95je/0RtvvKFXX31VkpScnCy73a4///nPrtfILbfcoj/+8Y86cuSIGjVqVOHHBQBfxRESAPCSwsJCDRw4UJs2bVJERIRat25d5n7VqlXTc88957peu3ZtRUREKD8//7L2u5TSsLFv3z7t3r1bHTp0UIsWLbR7927t27dPzZs3L/PDulGMeh6S1LVrV0nS4sWL9eOPP2rVqlX6+eefzzsyUqqkpERLly4t8/kdOHBA+/btU//+/V1hRJKaNGmi22+/XV9//bUOHTpU4Rq7dOniCiOS1Lt3b4WGhuqrr75y28disejZZ5/VunXrdOjQIUVFRWnu3Llq165dhR8TAHwZgQQAvOSrr77S119/rT/+8Y/as2eP/vKXv5S5X9OmTVW7dm23sYCA89+uy7vfpVx//fWqUaOG9u7dq927d6tNmzZq06aNK5BU5OjI5TDqeUhSfHy8IiIiNGXKFLVo0UJDhw5V9+7d9dRTT5W5/2233aZrr722zG3Z2dmSVObRiMjISEnS4cOHL1rP8ePHzxsLDw93u26xWFS7dm0dO3bMNdapUye98847Onr0qAYMGKDmzZurdevWmjNnzkUfDwD8EYEEALykZs2a+uijj/TQQw/pvvvu00svvVTmX9jr1KlTrvsr736XYrFY1KFDB6WlpWn//v2uQPLNN9/o22+/9XggMep5SNLo0aPVtWtXHThwQP/617+0Z88effTRR6pRo0aZ+4eEhFzwvurVqyfJOdH/XKVj54aLs9ntdn377bfnjZ/7O3c4HDpy5Mh5R2nuv/9+ffHFF/rpp5+UkpKi+Ph4TZkyRStWrLjgYwKAPyKQAICX3HDDDa7TbV588UUVFxdrypQp5hb1q06dOmnNmjWqVq2amjZtqjZt2mjdunXKy8u7okBy7l/+PW3Xrl2qXr266tSpoy5duigqKuqy76tZs2a67rrrtGbNGrcQcfDgQX300Udq166d61Qum82mI0eOqLi42LXfkiVLlJOTc979bt261S2ofPzxx8rPz1eXLl1cY6NGjVJMTIyKi4sVHBysdu3aadasWZKcE94BoDJhUjsAmKBRo0YaP368pk+frt/97neuZXbNEhsbq5KSErVq1UoWi0Vt2rRRSUmJQkJCXBPUL8dtt92ml156SVOnTtX111+vgwcPqkaNGhWerF5ecXFxWr58uUJCQtS6dWuFhYXp6quvVqtWrVynWVXEG2+8oTvvvFMJCQl6+OGHVVJSoj//+c+yWCyaO3eua7+EhAStW7dOzz77rMaMGaNNmzbpueeeU7Nmzc5bvrh69erq16+fHnnkEeXn52vu3LmqVauWW0/i4+O1fPly3XnnnbrrrrsUFBSkVatWuR4LACoTAgkAmOSxxx7T4sWLNWHCBG3ZskVBQUGm1VJ6FKRNmzaSpPr166tOnTpq0aKFAgMv/5+KiRMn6tSpU3r33Xd1+PBh1alT54LzOYwwZMgQrVq1Sv/4xz+0ePFiFRQUuLY99NBD+uMf/1ih+4uLi9OGDRv0/PPPa9asWbJYLEpISNBzzz3ntijB73//ex08eFDLli3TW2+9pY4dO+qDDz7QrFmz3L5nRnIuixwVFaXXXntNJ06cUFxcnGbPnq2GDRu6PY9q1arpzTff1IsvvqhTp04pOjpab775pu68887L7A4A+CZLfn6+w+wiAAC4Ut9//706duyo++67T127dlW1atVUUlKi3NxcvfPOO/rll1/cvuvDDDabTb/97W/15ptvmloHAPgSjpAAACqFZs2a6Q9/+IPWrl2rTz75RHl5ebrqqqsUHh6uzp0769FHHzW7RABAGThCAgAAAMA0rLIFAAAAwDQEEgAAAACmIZAAAAAAMA2BBAAAAIBpCCQAAAAATEMgAQAAAGAav/8ekl9++UVffvmlIiMjFRwcbHY5AAAAQJV2+vRpZWVlqWvXrqpZs+Yl9/f7QPLll19q4MCBZpcBAAAA4Czvvvuu7rjjjkvu5/eBpFGjRpKkNWvWqHnz5mXuY7fblZ+fL5vNJqvV6s3yKiX6aTx6aiz6aTx6aiz6aTx6aiz6aayq1s/09HTdfffdrs/pl+L3gaRatWqSpObNm6t169Zl7mO323XixAmFhYVViReBp9FP49FTY9FP49FTY9FP49FTY9FPY1XVfpZ+Tr8UJrUDAAAAMA2BBAAAAIBpCCQAAAAATEMgAQAAAGAaAgkAAAAA0xBIAAAAAJiGQAIAAADANAQSAAAAAKYhkAAAAAAwDYEEAAAAgGkIJAAAAABMQyABAAAAYBoCCQAAAADTEEgAAAAAmIZAAgAAAMA0BBIAAAAApiGQAADg4xwOacsWqaDA7EoAwHgEEgAAfNyGDdLNN0tNmkhz5hBMAFQuBBIAAHzczz87L7OzpfHjCSYAKhcCCQAAfiYnh2ACoPIgkAAA4GccDuclwQRAZUAgAQDAT5UVTObOlUpKTC0LACqEQAIAgJ8rDSbZ2dK4cVJysrn1AEBFEEgAAPBzFovzMiLCeYQkPt7cegCgIgLNLgAAAFwei8V5dCQ8XPrDH6SRI6WQELOrAoCKIZAAAOBnCCIAKhMCCQAAfoYgAqAyIZAAAODjrrnGeRkRQRABUPkQSAAA8HE9e0qbN0vt2hFEAFQ+BBIAAHycxSJ16WJ2FQDgGSz7CwAAAMA0BBIAAAAApiGQAAAAADANgQQAAACAaQgkAAAAAExDIAEAAPBzDoe0ZYtUUGB2JUDFEUgAAAD83IYN0s03S02aSHPmEEzgXwgkAAAAfu7nn52X2dnS+PEEE/gXAgkAAEAlk5NDMIH/IJAAAABUMg6H85JgAn9AIAEAAKikygomc+dKJSWmlgW4IZAAAABUcqXBJDtbGjdOSk42tx7gbAQSAACASs5icV5GRDiPkMTHm1sPcDaPBZKjR49q6NChioiIUM2aNdWnTx8dPHjQtb1Zs2ay2WxuPwsWLPBUOQAAAFVOaRAJD3fOITlwQHrkESmAP0nDhwR66o4HDx6s77//XpMnT1ZgYKBmzZql3/72t0pOTlZ2drYOHz6sv//976pXr57rNpGRkZ4qBwAAoMqwWJynaYWHS3/4gzRypBQSYnZVQNk8Ekg2btyo7du3KzU1VY0bN5YkhYWFafTo0crMzNT333+vsLAw9e7dW5bS6A4AAABDEETgTzwSSDp27KhNmza5wogk1apVS5J0+vRppaWlqX379oQRAAAAA1xzjfMyIoIgAv/jkTMIa9SooZYtW7qNrV+/XnXq1FHz5s21Y8cOZWVlqWXLlqpdu7YSEhL02WefeaIUAACASq9nT2nzZucckUcfJYzAv3hsDsnZ/vOf/2jZsmWaMmWKAgICtH37dtWtW1ePPfaYatSoofnz5+u+++7Ttm3bdN11113wfnJycnTkyBG3sYyMDEmS3W6X3W4v83al2y60HRVDP41HT41FP41HT41FP41HT6VOnZyXRrSAfhqrqvWzos/T44GkpKREDz/8sBo2bKgxY8ZIklauXKnmzZsrLCxMkpSYmKi2bdtq4cKFmjlz5gXv66233tL06dPL3Jafn68TJ06Uuc1ut+vkyZOSJKvVeiVPB6KfnkBPjUU/jUdPjUU/jUdPjUU/jVXV+pmfn1+h/T0eSF599VVt2bJF69evV/Xq1SVJ7du3dy8iMFCxsbHatWvXRe9r5MiR6t+/v9tYRkaGBg4cKJvN5go45ypNaWFhYVXiReBp9NN49NRY9NN49NRY9NN49NRY9NNYVa2fNputQvt7NJAkJSVp2rRpevbZZ3XTTTdJciam1NRUde/e3W3f3NxcFRYWXvT+6tWr57ZM8NmsVutFf8Gl26vCi8AbzOqnvciurJQsFeQWKKRWiCLjImUNqhy/U16jxqKfxqOnxqKfxqOnxqKfxqpK/azoc/RYINm3b58efPBB9e3bVxMmTHCNZ2Zmql+/ftq5c6eaN28uSTp48KA2b96skSNHeqoc+Dl7kV3JM5OVOi9V+dlnDgOGRoTqxtE3Kn5yfKUJJgAAAFWJRwJJUVGRHnzwQVksFo0ePVo7duxwbWvcuLHi4+M1YMAAjR49WqdPn9bcuXNls9k0duxYT5QDP2cvsmvl3Su1/5P90jkrRedl5ynpmST9uO1HDfhgAKEEAADAz3gkkOzZs0fffvutJOm2225z2/bXv/5VS5Ys0eOPP64pU6YoODhYvXr10vTp01W/fn1PlAM/lzwz2RlGJMlxzsZfr+//eL9SZqUo4akEr9YGAACAK+ORQNKuXbtLzq5funSpJx4alYy9yK7UeanOIyPnhpGzWaTUeamKmxTHURIAAAA/4pEvRgSMkpWS5ZwzcrEwIkkOKe9wnrJSsrxSFwAAAIxBIIFPK8gt8Oj+AAAAMBeBBD4tpFaIR/cHAACAuQgk8GmRcZGyhdvOW13rPBbnEsCRcZFeqQsAAADGIJDAp1mDrIodE1uuOSSxY2KZ0A4AAOBnCCTwefGT4xV9e7TzyrlHSn69Hn17tOImxXm1LgAAAFw5Agl8njXIqgEfDFDitESFhoe6bQsND1XitES+FBEAAMBPeeR7SACjWYOsSngqQXGT4pSVkqWC3AKF1ApRZFwkQQQAAMCPEUjgV6xBVkV1jzK7DAAAABiEU7YAAAAAmIZAAgAAAMA0BBIAAAAApiGQAAAAADANk9oBoDwWLZIyM6WoKGnYMHNrAQDgHPYiu9+uREogAYDyWLRI2rRJ6taNQAIA8Bn2IruSZyYrdV6q8rPzXeOhEaG6cfSNip8c7/PBhEACAAAA+CF7kV0r716p/Z/slyzu2/Ky85T0TJJ+3Pajz3+BNHNIAAAAAD+UPDPZGUYkyXHOxl+v7/94v1JmpXi1roriCAkAlGXRIudPqU2bzlx2735mfNgwTuECAHidvciu1HmpziMj54aRs1mk1HmpipsU57NHSQgkAFCWzMwzIeRcZ4+fHU4AAPCSrJQstzkjF+SQ8g7nKSslS1Hdozxe1+UgkABAWaKinBPYS50dQs4ej4ryVkUAALgU5BZ4dH9vIpAAQFnOPRWre/czq2wlJZlTEwAAvwqpFeLR/b2JSe0AAACAn4mMi5Qt3Hbe6lrnsTiXAI6Mi/RKXZeDQAIAAAD4GWuQVbFjYi8+oV2SHFLsmFifndAuccoWAJTPsGHO07aYMwIA8BHxk+P147Yftf/j/eevtvXr9ejboxU3Kc6kCsuHQAIA5cHSvgAAH2MNsmrABwOUMitFqfNSlXc4z7UtNDxUsWNifXq531IEEgAAAMBPWYOsSngqQXGT4pSVkqWC3AKF1ApRZFykzweRUgQSAAAAwM9Zg6w++z0jl8KkdgAAAACmIZAAAAAAMA2BBAAAAIBpCCQAAAAATEMgAQAAAGAaAgkAAAAA0xBIAAAAAJiGQAIAAADANAQSAAAAAKYhkAAAAAAwDYEEAAAAgGkIJAAAAABMQyABAAAAYBoCCQAAAADTEEgAAAAAmIZAAgAAAMA0BBIAAAAApiGQAADgA9KUpkEapLZqq0EapDSlmV0SAHhFoNkFAABQ1aUpTV3URQUqkCR9o2+0Vmu1RVsUoxiTqwMAz+IICQAAJpupma4wUqpABZqpmSZVBADeQyABAMBke7SnzPG92uvlSgDA+wgkAACYrLValzneSq28XAkAeB+BBAAAk03WZIUoxG0sRCGarMkmVQQA3kMgAQDAZDGK0RZt0UANVFu11UANZEI7gCqDVbYAAPABMYrRCq0wuwwA8DqOkAAAAAAwDYEEAAAAgGkIJAAAAABMQyABAAAAYBqPBZKjR49q6NChioiIUM2aNdWnTx8dPHjQtX379u3q3r27wsPDdccdd+iHH37wVCkAAAAAfJTHAsngwYOVkpKiyZMn68UXX9SePXv029/+VpJ08OBB3XnnnapevbqWLVumBg0a6J577lFRUZGnygEAAADggzyy7O/GjRu1fft2paamqnHjxpKksLAwjR49WpmZmXr99dcVFBSk999/XzabTT169FDbtm314Ycf6p577vFESQAAAAB8kEeOkHTs2FGbNm1yhRFJqlWrliTp9OnT+vzzz9WvXz/ZbDZJktVqVd++ffX55597ohwAAAAAPsojR0hq1KihGjVquI2tX79ederUUfPmzXXo0CG1adPGbXtkZKTWrVt30fvNycnRkSNH3MYyMjIkSXa7XXa7vczblW670HZUDP00Hj01ltH9tBfZ9cOWH1Twc4FCrglRoy6NZA2yGnLf/oLXqLHop/HoqbHop7GqWj8r+jy98k3t//nPf7Rs2TJNmTJFAQEBKigoUM2aNd32CQkJOS9snOutt97S9OnTy9yWn5+vEydOlLnNbrfr5MmTkpxHY3Bl6Kfx6KmxjOqnvdiunYt2au97e1WQW+Aar167ulre11LthrWTNbBq/L54jRqLfhqPnhqLfhqrqvUzPz+/Qvt7PJCUlJTo4YcfVsOGDTVmzBhJUrVq1c77ZQQHB+vUqVMXva+RI0eqf//+bmMZGRkaOHCgbDabwsLCyrxdaUoLCwurEi8CT6OfxqOnxjKin/Yiu1bdv0rpn6ZLFkmOM9tO/XBKKTtTlP1ltu5deW+VOFrCa9RY9NN49NRY9NNYVa2fpdMyysvjgeTVV1/Vli1btH79elWvXl2SVLduXR06dMhtv9zcXNf2C6lXr57q1atX5jar1XrRX3Dp9qrwIvAG+mk8emqsK+1n8vRk7f9w/0X32f+P/dr6ylYlPJVwWY/hb3iNGot+Go+eGot+Gqsq9bOiz9GjX4yYlJSkadOm6dlnn9VNN93kGu/UqZO2bt3qtu/OnTtVv359T5YDAOViL7IrdV6q88jIxVik1HmpshdVjXOCAQDwBI8Fkn379unBBx9U3759NWHCBLdtd999t9atW6fdu3dLcn4vyccff6zExERPlQMA5ZaVkqX87Hy307TK5JDyDucpKyXLK3UBAFAZeeSUraKiIj344IOyWCwaPXq0duzY4drWuHFj3XHHHerQoYP69u2rvn37asOGDapTp45+97vfeaIcAKiQsyewe2J/+BeHw6GUrBTFRcbJYrnUYTMAQEV55AjJnj179O233yo3N1e33Xabunbt6vr55JNPFBgYqA8//FBDhw7V7t27lZCQoI0bN+rqq6/2RDkAUCEhtUI8uj/8y7Jdy9R1YVct/2a52aUAQKXkkSMk7dq1u+RyX9WrV9eLL77oiYcHgCsSGRcpW7hN+TmXOG3LIoWGhyoyLtJrtcH7Vu5Z6bp8sO2DJlcDAJWPRye1A4A/sgZZFTsmtlxzSGLHxFaJZX+rquOFx7U+Y70k6dP0T3W88LjJFQFA5eOVL0YEAH8TPzleP277Ufs/3n/e95CUXo++PVpxk+JMqhCeYC+x69alt2p/rnPJ50J7oYpKiiRJRSVFin4jWtWs1SRJLWq30PrB6xVg4W97AHAlCCQAUAZrkFUDPhiglFkpSp2XqrzDea5toeGhih0Tq7hJcRwdqYROl5xW1vGyV07Lyc9x/Xfjmo3lcDguvTw0AOCiCCQAcAHWIKsSnkpQ3KQ4ZaVkqSC3QCG1QhQZF0kQqaSsAVZtGLJBT298WrM3z5ZFFjnOOjxWen1S3CS9kPiCrAG8DgDgShFIAOASrEFWRXWPMrsMeEmwNVizbpmlmlfV1JSNU9y2OeTQjJ4zNDl+sknVAUDlw4mvAACUYVfOrrLHs8seBwBcHgIJAADnOFV8Sh9+96EkKTAgUMPaDVNggPOkgg+//1Cnik+ZWR4AVCoEEgAAzrHvp33KL8pXdK1obRuxTQvvWqhtI7apea3myjudp30/7TO7RACoNJhDAgDAOWIiYvTZ4M90U6ObFBocKknqUL+Ddjy0Q1t/2KqYiBiTKwSAyoNAAgDAOQIsAerVtNd546HBoWWOAwAuH6dsAQAAADANgQQAAACAaQgkAAAAAExDIAEAAABgGgIJAAAAANMQSAAAAACYhkACAAAAwDQEEgAAAACmIZAAAAAAMA2BBAAAAIBpCCQAAAAATEMgAQAAAGAaAgkAAAAA0xBIAAAAAJiGQAIAAADANAQSAAAAAKYJNLsAoCqyF9mVlZKlgtwChdQKUYObGphdEgAAgCkIJIAX2YvsSp6ZrNR5qcrPzneNh0WGKebRGHUd21VWq9XECgEAALyLQAJ4ib3IrpV3r9T+T/ZLFvdteTl5+vqvXyv7y2wNWDVA1iBCCQAAqBqYQwJ4SfLMZGcYkSTHORt/vZ6+Ll0ps1K8WhcAAICZCCSAF9iL7Eqdl3rekZHzWKTUeamyF9m9UhcAAIDZCCSAF2SlZDnnjJx7ZORcDinvcJ6yUrK8UhcAAIDZCCSAFxTkFnh0fwAAAH9FIAG8IKRWiEf3BwAA8FcEEsALIuMiZQu3lWsOSWhEqCLjIr1SFwAAgNkIJIAXWIOsih0TW645JLFjYln2FwAAVBkEEsBL4ifHK/r2aOeVc4+U/Hq9eZ/mipsU59W6AAAAzEQgAbzEGmTVgA8GKHFaokLDQ922hdYL1Y0P36h7V97L0REAAFCl8E3tgBdZg6xKeCpBcZPilJWSpYLcAoXUClGDmxro5KmThBEAAFDlEEgAE1iDrIrqHuW6brfbpVPm1QMAAGAWTtkCAAAAYBoCCQAAAADTEEgAAAAAmIZAAgAAAMA0BBIAAAAApiGQAAAAADANgQQAAACAaQgkAAAAAExDIAEAAABgGr6pHQD8waJFUmamFBUlDRtmbi0AABiIQAIA/mDRImnTJqlbNwIJAKBSIZAA8E8cMQAAoFIgkADwTxwxAACgUiCQAIAvWrTI+VNq06Yzl927nxkfNoxABgDwawQSAPBFmZlnQsi5zh4/O5wAAOCHPB5INmzYoHHjxmn37t1u482aNdPhw4fdxubMmaMRI0Z4uiQA/qgiRwwGD/ZeXZ4SFeU8Ha3U2SHk7PGoKG9VBACAR3g0kHz33XcaPny4qlev7jaenZ2tw4cP6+9//7vq1avnGo+MjPRkOQD8WVU7YnDuqVjdu5+ZM5OUZE5NAAB4gMcCyfbt29W/f381adJEP/30k9u2tLQ0hYWFqXfv3rJYLJ4qAUBlwhEDAAAqJY8FkuTkZE2fPl2SXJel0tLS1L59e8IIgPKryBEDu917dQEAgCsS4Kk7fvTRRzX4Audx79ixQ1lZWWrZsqVq166thIQEffbZZ54qBQD837Bh0rPPsqIWAKDS8dgRkoCAC2ed7du3q27dunrsscdUo0YNzZ8/X/fdd5+2bdum66677oK3y8nJ0ZEjR9zGMjIyJEl2u132C/xVtHTbhbajYuin8ejpZbBapeBg5+U5fauU/Tz7DzwmPK9K2VMT0U/j0VNj0U9jVbV+VvR5mrLs78qVK9W8eXOFhYVJkhITE9W2bVstXLhQM2fOvODt3nrrrfNO/yqVn5+vEydOlLnNbrfr5MmTkiSr1XqF1YN+Go+eXoZhw6Rbb5UaNJDO+X+ffhqPnhqLfhqPnhqLfhqrqvUzPz+/QvubEkjat2/vXkRgoGJjY7Vr166L3m7kyJHq37+/21hGRoYGDhwom83mCjjnKk1pYWFhVeJF4Gn003j09DI88MAFN9FP49FTY9FP49FTY9FPY1W1ftpstgrt7/VAkp+fr9TUVHU/Z2nO3NxcFRYWXvS29erVc1sm+GxWq/Wiv+DS7VXhReAN9NN49NRY9NN49NRY9NN49NRY9NNYVamfFX2OHpvUfiGZmZnq16+f0tPTXWMHDx7U5s2bFRsb6+1yAAAAAJjI60dIWrdurfj4eA0YMECjR4/W6dOnNXfuXNlsNo0dO9bb5QAALmTRIucXUkZFuU+qBwDAQF4/QiJJS5YsUatWrTRlyhRNnz5dN910k7Zt26ZGjRqZUQ4AoCyLFknPP++8BADAQzx+hGTw4MHnfR9JvXr1tHTpUk8/NAAAAAAfZ8oREgAAAACQTFr2FwDggxYtcj89a9OmM5e33irVri0dPeqcT8I3xgMADEIgAQA4ZWaeCSHnSk6WIiOlrCypa1evlgUAqNwIJAAAp6goqVu3M9fPDifx8c4jJI0bO/cDAMAgBBIAgNOwYe6nYnXv7gwl3bpJ69dLJ05IYWFSFfhSLwCA9zCpHQAAAIBpCCQAAAAATMMpWwCAsg0b5jxtizkjAAAPIpAAAMp29nwSu920MqqqNKVppmZqj/aotVprsiYrRjFmlwUAhiOQAADgY9KUpi7qogIVSJK+0Tdaq7Xaoi2EEgCVDnNIAADwMTM10xVGShWoQDM106SKAMBzOEICAH7OXmRXVkqWCnILFFIrRJFxkbIGsTSvP9ujPWWO79VeL1cCAJ5HIAEAP2Uvsit5ZrJS56UqPzvfNR4aEaobR9+o+MnxBBM/1Vqt9Y2+OW+8lVqZUA0AeBanbAGAH7IX2bXy7pVKeiZJ+Tn5btvysvOU9EySVvZfKXsRk9H90WRNVohC3MZCFKLJmmxSRQDgOQQSAPBDyTOTtf+T/c4rjnM2/np9/8f7lTIrxat1wRgxitEWbdFADVRbtdVADWRCO4BKi1O2AMDP2IvsSp2XKll0fhg5m0VKnZequElxnLrlh2IUoxVaYXYZAOBxHCEBAD+TlZLlnDNysTAiSQ4p73CeslKyvFIXAACXg0ACAH6mILfg0jtdwf4AAHgTgQQA/ExIrZBL73QF+wMA4E0EEgDwM5FxkbKF25xzSC7G4lwCODIu0it1AQBwOQgkAOBnrEFWxY6JLdccktgxsUxoBwD4NAIJAPih+Mnxir492nnl3CMlv16Pvj1acZPivFoXAAAVRSABAD9kDbJqwAcDlDgtUaHhoW7bQsNDlTgtUQM+GMDREQCAz+N7SADAT1mDrEp4KkFxk+KUlZKlgtwChdQKUWRcJEEEAOA3CCQA4OesQVZFdY8yuwwAAC4Lp2wBAAAAMA2BBAAAAIBpCCQAAAAATEMgAQAAAGAaAgkAAAAA0xBIAAAAAJiGQAIAAADANAQSAAAAAKYhkAAAAAAwDYEEAAAAgGkIJAAAAABMQyABAAAAYBoCCQAAAADTEEgAAAAAmIZAAgAAAMA0BBIAAAAApiGQAAAAADANgQQAAACAaQgkAAAAAExDIAEAAABgGgIJAAAAANMQSAAAAACYhkACAAAAwDQEEgAAAACmIZAAgJ9KU5oGaZDaqq0GaZDSlGZ2SQAAVFig2QUAACouTWnqoi4qUIEk6Rt9o7Vaqy3aohjFmFwdAADlxxESAPBDMzXTFUZKFahAMzXTpIoAALg8BBIA8EN7tKfM8b3a6+VKAAC4MgQSAPBDrdW6zPFWauXlSpjLAgC4MswhAQA/NFmTtVZr3U7bClGIJmuyV+tgLgsA4Ep5/AjJhg0b1KZNm/PGt2/fru7duys8PFx33HGHfvjhB0+XAgCVRoxitEVbNFAD1VZtNVADTQkBzGUBAFwpjwaS7777TsOHD5fdbncbP3jwoO68805Vr15dy5YtU4MGDXTPPfeoqKjIk+UAQKUSoxit0AqlKU0rtMKUIxLMZQEAXCmPBZLt27erV69eaty48XnbXnvtNQUFBen999/XLbfcoj//+c/Kz8/Xhx9+6KlyAAAe4EtzWQAA/sljgSQ5OVnTp0/XyJEjz9v2+eefq1+/frLZbJIkq9Wqvn376vPPP/dUOQAAD5isyQpRiNuYGXNZAAD+y2OB5NFHH9XgwYPL3Hbo0KHz5pVERkYqPT3dU+UAADzAV+ayAAD8l8dW2QoIuHDWKSgoUM2aNd3GQkJCdOTIkYveZ05Oznn7ZGRkSJLsdvt5c1VKlW670HZUDP00Hj01Fv003sV62kZttEzL3PcXvb8YXqPGo6fGop/Gqmr9rOjzNGXZ32rVqslqtbqNBQcH69SpUxe93VtvvaXp06eXuS0/P18nTpwoc5vdbtfJkycl6bzHRcXRT+PRU2PRT+PRU2PRT+PRU2PRT2NVtX7m5+dXaH9TAkndunV16NAht7Hc3FxVr179orcbOXKk+vfv7zaWkZGhgQMHymazKSwsrMzblaa0sLCwKvEi8DT6aTx6aiz6aTxf76nD4dCWH7aoS6MuslgsZpdzSb7eT39ET41FP41V1fpZOk+8vEwJJJ06ddLWrVs1btw419jOnTtVv379i96uXr16qlevXpnbrFbrRX/BpdurwovAG+in8eipsein8Xy5p0vTlmrImiFa2n+pHmz7oNnllIsv99Nf0VNj0U9jVaV+VvQ5evyLEcty9913a926ddq9e7ck5/eSfPzxx0pMTDSjHACAn1u5Z6XbJQDAf5hyhOSOO+5Qhw4d1LdvX/Xt21cbNmxQnTp19Lvf/c6McgAAfux44XGtz1gvSfo0/VMdLzyuq6tdbXJVAIDyMiWQBAYG6sMPP9T06dO1ceNGJSQk6MUXX9TVV/MPCADg4uwldt269Fbtz90vSSq0F6qopEiSVFRSpOg3olXNWk2S1KJ2C60fvF4BFlNOCAAAlIPHA8ngwYPL/D6S6tWr68UXX/T0wwMAKqHTJaeVdTyrzG05+Tmu/25cs7EcDofk+/PcAaDK4k9GAGAyh8Oh5P8mOz8445KsAVZtGLJBT978pCTJck7aKL0+KW6SNgzZIGtA5Z9ACgD+jEACACZbtmuZui7squXfLDe7FL8RbA3WrFtmaXqP6XLIPcg55NCMnjM0s9dMBVuDz4wT/ADAJxFIAMBkrBB1+Xbl7Cp7PPv8cYIfAPgmAgkAadEi6bnnnJfwqrJWiEL5nCo+pQ+/+1CSFBgQqGHthikwwDk18sPvP9Sp4lNu+xP8AMA3mbLKFgAfs2iRtGmT1K2bNGyY2dVUaqwQZZx9P+1TflG+omtF691731WH+h30SKdHNGDVAKXnpmvfT/vUvn57SSwNDAC+jEACAF7GClHGiImI0WeDP9NNjW5SaHCoJKlD/Q7a8dAOpfw3RY+vf1zpuemSCH4A4Mt49wUAL2KFKOMEWALUq2kvVxgpFRocql5Ne6mopEhZx7OUdTzLLehJzuBXuq3QXshEdwAwEYEEqIoWLZK6dz/zs2mTc3zTJvdx5pR4xOWsEIWKIfgBgP/glC2gKsrMPBNCznX2ePfu3qimyqrIClGouNLgV/OqmpqycYrbttLgNzl+sknVAQBKEUiAqigqyjmBvdTZIeTs8agob1VU5Zy7QtSDbR/Usl3LVFxS7Foh6qrAq0yusnIg+AGAb+OULaAqGjZMSko681MaQrp1cx9nxS2POXuFqG0jtmnhXQu1bcQ2Na/VXHmn87Tvp31ml1gpVHRpYACA9xFIAMAEpStE/fuhf6tD/Q6SzqwQ9dngzxQTEWNyhZUDwQ8AfB+nbAGACUpXiDpX6QpRMMbFlgbe+sNWgh8A+AACCQDnqVnduzNnBJUOwQ8AfB+BBABzRQAAgGmYQwIAAADANAQSAAAAAKYhkAAAAAAwDYEEAAAAgGkIJAAAAABMQyABAAAAYBoCCQAAAADTEEgAAAAAmIZAAgBekqY0DdIgtVVbDdIgpSnN7JIAADAd39QOAF6QpjR1URcVqECS9I2+0Vqt1RZtUYxiTK4OAADzcIQEALxgpma6wkipAhVopmaaVBEAAL6BQAIAXrBHe8oc36u9Xq4EAADfQiABAC9ordZljrdSKy9XAgCAbyGQAIAXTNZkhSjEbSxEIZqsySZVBACAbyCQAIAXxChGW7RFAzVQbdVWAzWQCe0AAIhVtgDAa2IUoxVaYXYZAAD4FAIJAKByW7RIysyUoqKkYcPMrQUAcB4CCQCgclu0SNq0SerWjUACAD6IOSQAAAAATEMgAQAAAGAaTtkCAFQuixY5f0pt2nTmsnv3M+PDhnEKFwD4AAIJAKByycw8E0LOdfb42eEEAGAaAgkAoHKJinJOYC91dgg5ezwqylsVAQAugkACAKhczj0Vq3v3M6tsJSWZUxMA4IKY1A4AAADANAQSAAAAAKbhlC0AQOU2bJjztC3mjACATyKQAAAqN5b2BQCfxilbAAAAAExDIAEAAABgGgIJAAAAANMQSAAAAACYhkACAMBlcDikLVukggKzKwEA/0YgAQDgMmzYIN18s9SkiTRnDsEEQNkcDmnbNqmw0OxKfBeBBACAy/Dzz87L7Gxp/HiCCYCybdggJSZKd9whzZvHe0RZCCQAABggJ6fqBRN7kV2ZSZnat3qfMpMyZS+ym10S4HNK/3iRmytNnFi13iPKi0ACAIABHA7nZVUIJvYiuzZN26TXIl/T4sTFeu8372lx4mK9fu3r2jRtE8EEuIiq8B5RUQQSAAAMVFYwmTtXKikxtSzD2IvsWnn3SiU9k6T8nHy3bXnZeUp6Jkkr+68klAAXUJX+eFFeBBIAADyg9ENHdrY0bpyUnGxuPUZJnpms/Z/sd15xnLPx1+v7P96vlFkpXq0L8DeV/Y8XFUEgAQDAAywW52VEhPNDRny8ufUYwV5kV+q8VMlyiR0tUuq8VI6SAOVQWf94UREEEgAADFQaRMLDnadhHDggPfKIFFAJ/sXNSslSfnb++UdGzuWQ8g7nKSslyyt1Af6sMv7xoqJMe3v817/+JZvNdt7PqVOnzCoJAIDLVlYQefRRKSTE3LqMVJBbsZPcK7o/UJVU5j9eVFSgWQ+clpamjh076vXXX3cbr1atmjkFAQBwBcLDpT/8QRo5snKFkLOF1KrYE6vo/kBVYLE4T9OqCu8Z5WVaINm1a5diY2PVoUMHs0oAAOCyXXON8zIioup8qIiMi5Qt3OZcXetip21ZpNDwUEXGRXqtNsBfEETOZ9pBoZ07dxJGAAB+q2dPafPmynlq1oVYg6yKHRNbrjkksWNiZQ2yeqUuwJeV/vGidm3plVeq1ntGeZkSSI4dO6aMjAzNnz9f9evXV8OGDTV8+HAdPnzYjHIAAKgwi0Xq0qXqfaiInxyv6NujnVfOXW3r1+vRt0crblKcV+sCfFXPntLnn0v/+Ic0enTVe88oD1NO2fr3v/8th8Oh9u3b69lnn9WhQ4f03HPPafDgwfrss88ueLucnBwdOXLEbSwjI0OSZLfbZbeXvbxg6bYLbUfF0E/j0VNj0U/j0VNj+XU/A6R7V92rLa9u0dfzv1Zedp5rU2h4qDo+1FFdHu8iBcirz8+ve+qD6KexbrzRrhMnqk4/K/o8TQkkHTp00ObNmxUTE+Maa9iwofr166fdu3erTZs2Zd7urbfe0vTp08vclp+frxMnTpS5zW636+TJk5Ikq5XDx1eKfhqPnhqLfhqPnhqrMvQzZkyM2jzURtlp2So8VqhqNaopPCZc1kCrTp46KXl50czK0FNfQj+NVdX6mZ+fX6H9TQkkNWrUcAsjktSlSxdJzsnuFwokI0eOVP/+/d3GMjIyNHDgQNlsNoWFhZV5u9KUFhYWViVeBJ5GP41HT41FP41HT41VmfpZs3tNs0uQVLl66gvop7GqWj9tNluF9jclkGRmZio/P1+tW7d2jf3888+SpMLCwgverl69eqpXr16Z26xW60V/waXbq8KLwBvop/HoqbHop/HoqbHop/HoqbHop7GqUj8r+hxNmdQ+f/58jR8/3m1s+fLlkqTY2FgTKgIAAABgBlOOkAwdOlRvvvmmRowYoR49eigtLU1/+ctfdM8991zwdC0AVY+9yK6slCwV5BYopFaIIuMiWUYUAIBKxpRAcv3112vlypWaOnWqVq9erUaNGumll17S6NGjzSgHgI+xF9mVPDNZqfNSlZ99ZmJcaESobhx9o+InxxNMAACoJEz7pvZevXqpV69eZj08AB9lL7Jr5d0rtf+T/ed9x0Fedp6SnknSj9t+1IAPBhBKAACoBEz7pnYAKEvyzGRnGJHO/zboX6/v/3i/UmaleLUuAADgGQQSAD7DXmRX6rzU87/9+VwWKXVequxFVeMLpgAYw+GQtmyRCgrMrgTA2QgkAHxGVkqWc87IuUdGzuWQ8g7nKSslyyt1ofKyF9mVmZSpfav3KTMpk5BbyW3YIN18s9SkiTRnDsEE8BWmzSEBgHMV5Fbs00FF9wdKsXBC1fTrV54pO1saP16aMUP6wx+kUaOkkBBTSwOqNI6QAPAZIbUq9omgovsD0pmFE5KeSVJ+Tr7bttKFE1b2X8nRkiogJ8cZTDhiApiLQALAZ0TGRcoWbivXHJLQiFBFxkV6pS5ULiycgFKOX3/fBBPAXAQSAD7DGmRV7JjYcs0hiR0Tyyk1qDAWTkBZygomc+dKJSWmlgVUGQQSAD4lfnK8om+Pdl4590Pjr9ejb49W3KQ4r9aFyoGFE3AxpcEkO1saN05KTja3HqCqIJAAuGwOh0PJ/02Ww3GpT3flZw2yasAHA5Q4LVGh4aFu20LDQ5U4LdFnvxTxueee03PPPWfa42dnZ6tPnz6qW7eubrvtNh09etS0WnwVCyfgYiy//tEjIsJ5hCQ+3tx6gKqCVbYAXLZlu5ZpyJohWtp/qR5s+6Bh92sNsirhqQTFTYpTVkqWCnILFFIrRJFxkT4ZRHzFAw88oGuvvVaHDx/WW2+9pXHjxmnZsmVml+VTWDgBZbFYnEdHwsOdq26NHMmqW4A3EUgAXLaVe1a6Lo0MJKWsQVZFdY8y/H4ro//973/auHGjDh06JKvVqlGjRun555/XqVOndNVVV5ldns8oXTghP+cSp21ZnEfkWDihciOIAL6BU7YAXJbjhce1PmO9JOnT9E91vPC4yRV5xz//+U/dcMMNqlu3rhITE3XgwIGL7v/jjz/qlltuUYMGDdS8eXOtXr3ate1f//qXWrdurXr16qlDhw5KS0tzbXvttdfUuHFj1a1bV/369dOxY8cu+jgHDx5Uo0aNFBERIUkKCAhQRESE/vOf/1zBs618WDgBZwsPd66qdeCA9OijhBHALAQSAOViL7Gr5+Keuva1a3Xta9cq+o1oFZUUSZKKSooU/Ua0a1uvJb1U4qh8y9Okp6dr0KBBWrBggQ4fPqwuXbpo7NixF73NokWLFBsbq//9739auXKlRo8e7dr2xBNP6LHHHlNOTo7GjRunjz76SJL0888/a8KECdqwYYMOHz6sli1b6ssvv9ShQ4cUERFx3k/37t1VUlKia665xu2xbTabfvnlF8P74O9YOKHqKv1fJCKCIAL4Ek7ZAlBup0tOK+t42asO5eTnuP67cc3Gzonul1pa1c98+umnuvnmm9W5c2dJ0vTp0y95m0mTJukf//iHHn/8cX3xxRfKzs52bUtMTNS8efN05MgRJSQkaOjQoZKkGjVqqEOHDnr88cfVu3dvjRo1StHRzg/Qhw8fLvNxvv32W+Xm5rqN5efny2rlL/znKl04IWVWilLnpSrvcJ5rW2h4qGLHxCpuUhxHRyqhnj2lzZuldu0IIYAv4QgJgHKxBli1YcgGPXnzk5Ikyzlpo/T6pLhJ2jBkg6wBlfPDnMVy5nnn5uZq/vz5F93/7rvv1tKlSxUfH6+1a9e6bXvttde0aNEi1axZU4888ojr6ElAQIC2bt2qxx9/XMePH1e3bt307rvvXvRxoqOjVVxcrP37nV/4d+zYMe3bt0+NGze+nKdZ6ZUunDD+v+M19POhuv/v92vo50M1/r/jlfBUAmGkkrJYpC5dCCOAryGQACi3YGuwZt0yS9N7TJfjnJPwHXJoRs8ZmtlrpoKtwSZV6Fm9e/fW5s2blZqaKklasGCBlixZctHbfPHFFxo1apT69u173opX119/vU6cOKGHH35Yo0eP1pdffinJeWpYq1at1LJlS02ePFm9evVSSsrFvzXcarVq+PDhGj58uJKTk/Xwww+re/fuCg8Pv4JnXPmVLpzQ8p6WiuoeRRABABNwyhaACtuVs6vs8eyyxyuL5s2ba+nSpfrd736no0ePqnXr1pcMJC+88IKGDBmiq666SoMGDVJoaKi+/fZbXX/99frjH/+ohx56SD/99JNq1qypV1991fU4//d//6cOHTqosLBQzZo109KlSy9Z3wsvvKCXXnpJY8eOVatWrbR48WJDnjcAAJ5kyc/PN+4bzUywd+9excbGavfu3WrdunWZ+9jtdp04cUJhYWGcT20A+mk8f+rpqeJTqjO7jvKL8hUYEKgH2z6oZbuWqbikWKHBofpp4k+6KtDcZWb9qZ/+gp4ai34aj54ai34aq6r1c8+ePWrTpo1SU1PVqlWrS+7PKVsAKmTfT/uUX5Sv6FrR2jZimxbetVDbRmxT81rNlXc6T/t+2md2iQAAwI9wyhaAComJiNFngz/TTY1uUmhwqCSpQ/0O2vHQDm39YatiImJMrhAAAPgTAgmACgmwBKhX017njYcGh5Y5DgAAcDGcsgUAAADANAQSAAAAAKYhkAAAAAAwDYEEAACgknI4pC1bpIICsysBLoxAAgAAUElt2CDdfLPUpIk0Zw7BBL6JQAIAAFBJ/fyz8zI7Wxo/nmAC30QgAQAAqCJycggm8D0EEgDwIzt37tSIESO0detWs0sB4IccDuclwQS+hEACAH5g586d6t+/v9q3b6+3335b//d//2d2SQD8WFnBZO5cqaTE1LJQRRFIAMCHnR1E1qxZY3Y5ACqZ0mCSnS2NGyclJ5tbD6omAgkA+CCCCMzGcrFVg8XivIyIcB4hiY83tx5UTQQSAPAhBBH4CpaLrdxKg0h4uPP3e+CA9MgjUgCfDGECXnYA4CPWrFlDEIHPYLnYyqmsIPLoo1JIiLl1oWojkAAAvGvRIum555yX8BusylQ5EETgiwgkAOAj7r77bu3YsUP9+/c3uxTPWrRIev55AomfYblY/3TNNc7LiAiCCHwXgQQAfEi7du20evXqqhFM4JdYLta/9Owpbd5MEIFvI5AAgA8imMDXsVysf7BYpC5dCCLwbQQSAPBhlSKYLFokde9+5mfTJuf4pk3u45zC5VdYLhaAUQLNLgAAcGmlwWTnzp2aN2+eRowYYXZJ5bNokfOnNISc6+zx7t29UBCulMXiPDoSHi794Q/SyJH89R3AlSGQAIAfadeund566y2zyyi/0jBSo4bUrp1z7OwQ0q3bmf+OivJiYagoggiqAodD2rrV+XbF69t7CCQAAM9r105KSnL+d+lpW926nRmDzyOIoCrYsEG65ZYzr/dRo3i9ewNzSAAAwHlYLhZVEV8Iag6OkAAAjFM6Z6TUuRPYJWnnTu/WhMtSulwsp66gKitd3nrGDI6YeBJHSAAvczikLVv4awsqqcxMZ/go/Tlb6dixY87TtYYNM6NClBPLxQJ8Iai3EEgAL9uwQbr5Zt7UUElFRTnDRunP2c4eHzaMQALAb/CFoJ7FKVuAl517fuqMGdKUKdKAAVJYmKmlAVfu3KDBBHYAlci5Xwjarp2UkGBqSZUCR0gAk+XkSBMnSnfcIc2bxxETAAB8FV8I6hkEEsBkpX9tyc11BhNO5QIAwLeUBpHw8DOrzj3yiBTAJ2lD0EbAx3B+KiqVYcOkZ59lvggAv1RWEGH5a+MxhwTwMZyfikqFIALAj/GFoN5BIAF8jMXiDCUREc7J7pyfCgCAd5z9haAEEe8hkAA+hr/GAABgDr4Q1BwEEsBkpeen1q7tPEVrxAjeBAEAMEPpF4LCuwgkgMnCw52nZt1/v1SnjmS1ml0RAACA95i6ytbrr7+uFi1aqHHjxnrhhRdUwnJCqALOPj+1dMWO0aOlatXMrQsAAMAMph0h+dOf/qSnnnpKU6ZMUYcOHTRx4kTZbDY9/vjjZpUEeEVZ56fa7aaWBAAAYBpTAsnp06c1Y8YMjRgxQlOmTJEkhYSEaNCgQRo3bpwCAzmTDJUX56cCAACcYcopW//+97/1yy+/aMCAAa6xbt26SZK+/vprM0oCAAAAYAJTAsmhQ4ckSW3atHEbb9iwodLT080oCQAAAIAJTDk3qqCgQFarVWFhYW7jISEhOnLkyAVvl5OTc972jIwMSZLdbpf9Aifil2670HZUDP00Hj01Fv00Hj01Fv00Hj01Fv00VlXrZ0WfpymBpFq1amXOEwkODtapU6cueLu33npL06dPL3Nbfn6+Tpw4UeY2u92ukydPSpKsrKl6xein8eipsein8eipsein8eipseinsapaP/Pz8yu0vymBpG7duiosLNTRo0dVu3Zt1/jPP/+s6tWrX/B2I0eOVP/+/d3GMjIyNHDgQNlstvOOuJQqTWlhYWFV4kXgafTTePTUWPTTePTUWPTTePTUWPTTWFWtnzabrUL7mxJIYmJiFBwcrK1bt+r222+XJJ04cUL79+9X/fr1L3i7evXqqV69emVus1qtF/0Fl26vCi8Cb6CfxqOnxqKfxvOXnjoc0tat7ktr+yJ/6ac/oafGop/Gqkr9rOhzNGVSe40aNdSjRw/NmTPHlRjnz58vh8PhWm0LAIDLsWGDdPPNUpMmzi8fLSgwuyIAwMWY9k3tTz31lL7++mt1795dgwcP1nPPPaeHH35YdevWNaskAEAl8PPPzsvsbGn8eIJJZeFwOJT832Q5HA6zSwFgMNMCSfv27bVp0yY1aNBA//nPfzRt2jTNnDnTrHIAAJVUTo5xwcThkLZsIdyYYdmuZeq6sKuWf7Pc7FIAGMy0QCI5v4dk5cqVSk5O1mOPPVYlzqkDAHhX6R/UjQgmnA5mnpV7VrpdAqg8TA0kAAB4S1nBZO5cqaSk/PfB6WDmOF54XOsz1kuSPk3/VMcLj5tcEQAjmbLKFnAh9iK7slKyVJBboJBaIYqMi5Q1iCNnAIxTGkyys6Vx45yrcSUkXN59lYabGTOkP/xBGjXKt1f28hf2ErtuXXqr9ufulyQV2gtVVFIkSSoqKVL0G9GqZq0mSWpRu4XWD15vWq0ArhyBBD7BXmRX8sxkpc5LVX72mS/TCY0I1Y2jb1T85HiCCeAnfH3ZXYvFWWNEhDRlihQff/n3de5RF4KJcU6XnFbW8awyt+Xk57j+u3HNxkx0B/wcp2zBdPYiu1bevVJJzyQpP8f9mz3zsvOU9EySVvZfKXuR3aQKAVSEr86zsFicl+HhzroOHJAeeUQKMOBfQiNOB8MZ1gCrNgzZoCdvflKSZJHFbXvp9Ulxk7RhyAZZA/iDFeDPCCQwXfLMZO3/xHlYXuf+kevX6/s/3q+UWSlerQvA5fG1eRZlBZFHH/XMEYxzTwdLTjb+MaqKYGuwZt0yS9N7TJfjnH8cHHJoRs8ZmtlrpoKtwSZVCMAonLIFU9mL7EqdlypZdH4YOZtFSp2XqrhJcZy6BfgZs09nCg93Pu7IkV543Jg0adJMBcbsUdvA1gprPllSjIcftHLblbOr7PHsssfhW0pKSpSdna3CwkKVVOFDhg6HQ0VFRTp69KgsFsulb+CDAgICVK1aNYWHhyvAiEPLZ9+3ofcGVFBWSpZzzsilTv91SHmH85SVUvb5xAB8l5HL7pbHNdc4LyMiPH9EpJTFIqltmrSlizToXRW3/Eb/bvGu4gK6KE1pnnvgSu5U8Sl9+N2HkqTAgEANazdMgQHOv6V++P2HOlV8yszycAklJSX673//q19++UWnT5+u8nN9AgP99ziAw+HQ6dOn9csvv+i///2v4eHSfzuDSqEgt2KfSCq6PwDfUdYE8ClTpLFjjZnHUapnT2nzZu9Mqi+dIB8eLjV4b6b+HfLre9SvfwAtUIFmaqZWaIVnC6mk9v20T/lF+YquFa13731XHep30COdHtGAVQOUnpuufT/tU/v67c0uExeQnZ2tgoIC1apVS/Xq1fPbIwNGcDgcstvtslqtftsHh8OhnJwc5ebmKjs7W/Xr1zfsvjlCAlOF1KrYp4WK7g/A93h6noXFInXp4p3Tws6el1J03Z4y99mrvZ4vpJKKiYjRZ4M/078f+rc61O8gSepQv4N2PLRDnw3+TDERnA7nywoLC2W1Wqt8GKksLBaL6tWrJ6vVqsLCQkPvm0ACU0XGRcoWbpMu9T5lcS4BHBkX6ZW6AHhO6eeSiAjnSlRXsuyut13sdLDWal3mbVqplRcrrFwCLAHq1bSXQoND3cZDg0PVq2kvBVj4GOPLSkpK/PqIAM5nsVhktVoNP2WL/5NhKmuQVbFjYss1hyR2TCwT2gE/5slld72l9HSwsualTNZkhcj9sEyIQjRZk71cJeA7CCOVjyd+p370zwAqq/jJ8Yq+Pdp55dzX+K/Xo2+PVtykOK/WBcAY3lx219MudjpYjGK0RVs0UAPVVm01UAO1RVsUwypbAHBRTGqH6axBVg34YIBSZqUodV6q8g7nubaFhocqdkwsy/0Cfsyry+6aLEYxTGAHgAoikMAnWIOsSngqQXGT4pSVkqWC3AKF1ApRZFwkQQTwM2fPs6gqQQQAypKZmakmTZrowIEDioz0zXmw69at08SJE/Xf//5XvXv31vz583VN6Ru5l3DKFnyKNciqqO5RanlPS0V1jyKMAH7oYvMsAAC+46uvvtKdd96pVq1a6f3339fJkyf129/+1ut1cIQEAGCo0nkWAOAxixZJmZlSVJQ0bJi5tfix5557Ttddd51WrFihgIAA3XTTTWrUqJFSU1MVGxvrtTo4QgIAAAD/smiR9PzzzktcFrvdrqSkJA0cOFABvy53ePXVVysxMVH/+te/vFoLgQQAAACooMLCQk2YMEF169ZVzZo11a9fP2VkZJT79unp6brttttUo0YNhYeHa9SoUSooKHC7/3HjxqlBgway2Wzq0qWLvvrqK7f7WL16tdq2bavq1aurcePGevnll13b7Ha7iouLy/wpKSnRzz//rIKCArVt29btPq+99lrt37//MrtyeQgkAAAAQAUNGTJEixcv1uzZs7Vq1SodO3ZMffr0UVFR0SVv63A41K9fPx0+fFirV6/Wm2++qY8//livvPKKa58ZM2bo7bff1iuvvKK1a9eqYcOGuuuuu+RwOL+8LT09Xffff7/i4+P16aef6oknntDkyZO1bt06SVLPnj0VFBRU5s/w4cNd4efcCewhISH66aefjGpTuTCHBAAAAL5t0SL307M2bTpz2b37mfFhw7wyp+T777/Xe++9p8WLF2vIkCGSpLp162ratGnKzs5Wo0aNLnr7kydPavz48UpMTNR1112nkpISLVmyRFu2bHHtk5mZqWuvvVaDBg2SxWJRTEyMtm3bpuLiYgUFBemHH36Q3W7X0KFD1blzZ3Xt2lUtW7ZU06ZNJUkLFixQXl5emY9fq1YtVatWTZJktbovIBQcHOx2pMYbCCQAAADwbZmZZ0LIuc4ePzuceNDOnTslSQkJCa6xmJgYrVq1qly3t9lsuueee7R48WIlJSVp27Ztys3Ndbu/4cOH6/3331fbtm3VrVs3xcXFqX///goKCpIk3XzzzerQoYP69u2r3r17KzY2Vv3791eTJk0kSc2bN79oDXa7XVarVf/73//cxnNzc2Wz2cr1PIzCKVuAD3A4HNp5eKfrMCwAADhLVJTUrduZn7OdPR4V5ZVySv+9tlgsbmPJyck6fPjwJW+flZWlVq1aae3atbr11lu1Zs0aTZ061W2fhIQEpaena+LEiSoqKtLYsWPVuXNnnTp1SpLzSMbWrVv1t7/9Tc2bN9fy5ct1/fXXKykpqVzPwWq16sYbb1RKSorb+Ndff60GDRqU6z6MQiABfMCKb1ZoxD9G6N3d75pdCgAAvmfYMCkp6cxPaSjp1s193EtLALdv316S9MUXX7jGMjMz1bVrV6Wmpl7y9qtXr9bx48e1YcMGjRs3TvHx8edNJJ89e7b279+vIUOGaP78+froo4+0a9cu12ldSUlJmjNnjvr06aNp06Zp+/btatKkiRYuXFju53Hvvfdq6dKlrqMkW7du1VdffaVevXqV+z6MwClbgA9YtW+V6/LBdg+aXA0AALiYFi1a6L777tOECRNkt9vVqFEjvfTSS2rWrJl69OhxydvXqVNHRUVFWrhwoaKjo7Vw4UKtXLlScXFxrn0yMjK0dOlSvfjii6pdu7befvttWa1WNW7cWJIUFBSkqVOnKjAwUJ06ddJ3332ngwcP6oEHHij38xg1apTmz5+vzp07q1evXlq9erU6duyou+66q+JNuQIcIQFMdrzwuDYc2CBJ+lfGv3S88LjJFQEAgEtZsmSJBg8erIkTJ+q+++5TjRo19Nlnn5Vr/sXAgQM1duxYTZ06VQ888ICKi4v19NNPa/fu3Tp27Jgk6ZVXXlF8fLzGjBmjW265RampqVqxYoVr0npcXJwWLFigd955R7169dIf/vAHDR8+XJMmTSr3c7j66qu1detW3X777dq5c6d++9vf6rPPPlNgoHePWVjy8/P9+qT1vXv3KjY2Vrt371br1q3L3Mdut+vEiRMKCws7byUBVBz9vDL2ErtuXXqr9uc6D80W2gv1y8lfFHlVpLJOZalm9ZqqZnWufNGidgutH7xeARb+dlAR/voadTgcSslKUVxknNt5yb7AX3vqq+in8eipsYzo54EDByTJ9QHaUH72Te0Oh8M1idzX3t8rqjy/1z179qhNmzZKTU1Vq1atLnmfnLIFmOB0yWllHc9yXQ+2BLv+Oyc/x/XfjWs2dk6c8+/3LpTTsl3LNGTNEC3tv1QPtuXUPQC4ID8IISg//uwKeJk1wKoNQzboyZuflCRZzkkbpdcnxU3ShiEbZA3gL31Vxco9K90uAQCoCggkgAmCrcGadcssTe8xXQ65nzXpkEMzes7QzF4zFWwNvsA9oLI5Xnhc6zPWS5I+Tf+UuUQAgCqDU7YAE+3K2VX2eHbZ46g8yppLVFRSJEkqKilS9BvRzCUCAFQJ/OsGmORU8Sl9+N2HkqTAgED1u66fAgOcfyP48PsPdar4lJnlwQtK5xJlHc9ymzskOecSlW4rtBfypZkAgEqLQAKYZN9P+5RflK/oWtHa9LtNeq7bc9r0u01qXqu58k7nad9P+8wuER7EXCIAAJw4ZQswSUxEjD4b/JluanSTQqwhOnHihNpHtNeOh3Zo6w9bFRMRY3aJ8LDSuUQ1r6qpKRunuG0rnUs0OX6ySdUBAOAdBBLAJAGWAPVq2kuSc733UqHBoa5xVA3MJQIAVGWcsgUAJjp3LtGwdsOYSwQAqFIIJABgorPnEm0bsU0L71qobSO2MZcIACqBzMxMWSwWZWZmml3KRf3vf/9TRESEaXVyyhYAmOjsuUShwaGSpA71OzCXCADgFSdOnNC9996r7Oxs02ogkACAic6eS3Q25hIBQNnsRXZlpWSpILdAIbVCFBkXKWsQKxFejiNHjqhXr14KDjb3i5gJJAAAAPB59iK7kmcmK3VeqvKz813joRGhunH0jYqfHE8wqaA9e/aoW7dueuSRRxQdHW1aHcwhAQAAgE+zF9m18u6VSnomSfk5+W7b8rLzlPRMklb2Xyl7kf0C92C8wsJCTZgwQXXr1lXNmjXVr18/ZWRklPv26enpuu2221SjRg2Fh4dr1KhRKigocLv/cePGqUGDBrLZbOrSpYu++uort/tYvXq12rZtq+rVq6tx48Z6+eWXXdvsdruKi4vL/CkpKZEkde3aVXPmzFFgoLnHKAgkAAAA8GnJM5O1/5P9ziuOczb+en3/x/uVMivFazUNGTJEixcv1uzZs7Vq1SodO3ZMffr0UVFR0SVv63A41K9fPx0+fFirV6/Wm2++qY8//livvPKKa58ZM2bo7bff1iuvvKK1a9eqYcOGuuuuu+RwOJ9wenq67r//fsXHx+vTTz/VE088ocmTJ2vdunWSpJ49eyooKKjMn+HDh0uSAgJ8IwpwyhYAAAB8lr3IrtR5qZJF54eRs1mk1HmpipsU5/FTt77//nu99957Wrx4sYYMGSJJqlu3rqZNm6bs7Gw1atToorc/efKkxo8fr8TERF133XUqKSnRkiVLtGXLFtc+mZmZuvbaazVo0CBZLBbFxMRo27ZtKi4uVlBQkH744QfZ7XYNHTpUnTt3VteuXdWyZUs1bdpUkrRgwQLl5eWV+fi1atUyqBPGIJAAAADAZ2WlZLnNGbkgh5R3OE9ZKVmK6h7l0Zp27twpSUpISHCNxcTEaNWqVeW6vc1m0z333KPFixcrKSlJ27ZtU25urtv9DR8+XO+//77atm2rbt26KS4uTv3791dQUJAk6eabb1aHDh3Ut29f9e7dW7Gxserfv7+aNGkiSWrevLlBz9bzfOM4DQAAAFCGgtyCS+90BftfjtLTpiwWi9tYcnKyDh8+fMnbZ2VlqVWrVlq7dq1uvfVWrVmzRlOnTnXbJyEhQenp6Zo4caKKioo0duxYde7cWadOOb8wNzg4WFu3btXf/vY3NW/eXMuXL9f111+vpKQk456olxBIAAAA4LNCaoV4dP/L0b59e0nSF1984RrLzMxU165dlZqaesnbr169WsePH9eGDRs0btw4xcfHa//+/W77zJ49W/v379eQIUM0f/58ffTRR9q1a5frtK6kpCTNmTNHffr00bRp07R9+3Y1adJECxcuNPCZegenbAHwCawrDwAoS2RcpGzhNufqWpeYQxIaHqrIuEiP19SiRQvdd999mjBhgux2uxo1aqSXXnpJzZo1U48ePS55+zp16qioqEgLFy5UdHS0Fi5cqJUrVyouLs61T0ZGhpYuXaoXX3xRtWvX1ttvvy2r1arGjRtLkoKCgjR16lQFBgaqU6dO+u6773Tw4EE98MADHnvenkIgAWAq1pUHAFyMNciq2DGxSnom6eI7OqTYMbFe+zdjyZIlmjJliiZOnKji4mJ169ZN77zzjmw22yVvO3DgQG3dutUVKBITE/X0009r7ty5OnbsmGrUqKFXXnlFTz75pMaMGaOjR4+qWbNmWrFihWvSelxcnBYsWKCXX35ZU6ZM0dVXX63hw4dr0qRJnn7qhrPk5+dfLGv6vL179yo2Nla7d+9W69aty9zHbrfrxIkTCgsLk9XKB5srRT+NV1V7Wrqu/P5P9p+/esqv16Nvj9aADwZU6B+YqtpPT6KnxqKfxqOnxjKinwcOHJAk1wfoK6qnyK6V/Vdq/8fG/nvhLQ6HQ3a7XVar1W3eiT8qz+91z549atOmjVJTU9WqVatL3idzSACYxhfXlQcA+B5rkFUDPhigxGmJCg0PddsWGh6qxGmJPhtGcGmcsgXAFL64rjwAwHdZg6xKeCpBcZPimHNYyRBIAJjCF9eVBwD4PmuQlX8PKhkCCQBT+OK68vBhixZJmZlSVJQ0bJi5tQAADEUgAWAKX1xXHj5s0SJp0yapWzcCCQBUMkxqB2CK0nXldanFRizOJYC9sa48AADwPgIJAFOUrit/0QntktfXlQcAAN5lWiBp1qyZbDab28+CBQvMKgeACeInxyv69mjnlXOPlPx6Pfr2aMVNihOqmEWLpO7dz/xs2uQc37TJfXzRInPqAwAYxpQ5JNnZ2Tp8+LD+/ve/q169eq7xyEhOyQCqktJ15VNmpSh1XqryDue5toWGhyp2TCzL/VZVmZlnQsi5zh7v3t0b1QAAPMiUQJKWlqawsDD17t3b77+tEsCVYV15lCkqyjmBvdTZIeTs8agob1UEABWWmZmpJk2a6MCBAz75h/eSkhI9++yzeuutt3TkyBE1bdpU8+bN0y233OLVOkwLJO3btyeMAHBhXXlIcl/eNynpzHjpaVvdurmPAwAu24svvqhXXnlFY8eOVcuWLfX666+rf//+Sk9PV0REhNfq8MgckpKSEhUXF5f5Y7fbtWPHDmVlZally5aqXbu2EhIS9Nlnn3miFACAP1m0SHr+eeaGAHBxOKQtW6QCvo7KUMeOHdPLL7+spUuX6uWXX9bw4cP1wQcfKD8/X//85z+9WotHjpA8/PDDWr58eZnbunbtqgMHDqhu3bp67LHHVKNGDc2fP1/33Xeftm3bpuuuu+6C95uTk6MjR464jWVkZEiS7Ha77HZ7mbcr3Xah7agY+mk8emos+mk8r/XUapWCg52XZz/Whcb9FK9R49FTYxnRT4fD4XZ5uf71L+nWWy0KD3do8mRp1CgpxE++murcHlxpL4x01VVX6fPPP1fHjh1dddWqVUuSVFhYeMFaS8cv9tqo6OvGI4Hk6aef1pgxY8rcFhoaquPHj6t58+YKCwuTJCUmJqpt27ZauHChZs6cecH7feuttzR9+vQyt+Xn5+vEiRNlbrPb7Tp58qQkyWrlnPQrRT+NR0+NRT+N57We1q4tRUY6L89+Tx82TLr1VqlBA/dxP8Vr1Hj01FhG9LOoqEiBgYFXHBKPHrVIsio7W3rsMYtmzHBo0qQSjRzpMDWYFBYWaurUqVq+fLmKiooUFxenP/7xj2rWrJlrn9LnXlJSopKSErfbp6en67HHHtPmzZt11VVX6Y477tBrr72mkF+fVGFhoSZPnqy///3vOnbsmG644Qb98Y9/VKdOnVz38cEHH+iFF15QRkaG6tatq9GjR+vxxx93PfaFQkVAQICsVqvatWvn9vv5+OOPJUk33XTTBX9vDodDxcXFF/zcLTk/l1eERwJJZGRkhSbuBAYGKjY2Vrt27brofiNHjlT//v3dxjIyMjRw4EDZbDZXwDlXaUPDwsJ4kzIA/TQePTUW/TSex3q6dKnzp1RysvMyK0s6evTM+ODB0hNPGPe4JuM1ajx6aiwj+nn01/+Hr/T3EeCaYOCce/zTT9Ljj1s1e7a5R0yGDx+uf/3rX3r55ZcVGRmpF154Qf369dOePXsUFBQk6cxzDwgIcP1YLBY5HA7dfffdql69uv7+978rLy9PY8aM0bXXXqunn35akjR79mwtXLhQ8+fPV7169TR//nz95je/0Y8//iiLxaL09HQNGjRII0eO1Lx587Rz50499thjatu2rfr06aNevXpp0wVWKxw6dKgWLlzoNlZUVKTp06fr1ltvVUxMzAWft8ViUVBQ0AU/d0uSzWarUC+9Pqk9Pz9fqamp6n7OUo25ubkqLCy86G3r1avntkzw2axW60Vf8KXbeZMyBv00Hj01Fv00nkd6mpkpbdxY9razx7t2dZ6uVYnwGjUePTXWlfazdPGiK13E6NybOxzOgZwcix57TJo5U/rDH7wbTL7//nu99957Wrx4sYYMGSLJ+Tl12rRpysnJUaNGjX6t3XLepcVi0cmTJzV+/HglJibquuuuU0lJiZYuXaqtW7e69j148KCuvfZaPfDAA7JYLGrXrp22bdsmu92uoKAg/fjjj7Lb7Ro2bJg6d+6shIQEtWrVSk2bNpXFYtGCBQuUl5dXRvXOU7PO/b1MmzZN6enpWrly5UV/Z6XbLvW5uyK8HkgyMzPVr18/7dy5U82bN5fkbPjmzZs1cuRIb5cDADATy/sCuEylZyPl5Ejjx0szZkhTpkhjx559VMUzdu7cKUlKSEhwjcXExGjVqlXlur3NZtM999yjxYsXKykpSdu2bVNubq7b/Q0fPlzvv/++2rZtq27duikuLk79+/d3HX25+eab1aFDB/Xt21e9e/dWbGys+vfvryZNmkiS63N2eXz55ZeaMWOGpk+frhtuuKHctzOK17+pvXXr1oqPj9eAAQP09ttv6y9/+Yv69Okjm82msWPHerscAICZhg1zLuNb+lMaQkqX9y39GTbMnPoA+LzSYJKdLY0bd+bMT88+pvNBzz6S4HA4lJycrMOHD1/y9llZWWrVqpXWrl2rW2+9VWvWrNHUqVPd9klISFB6eromTpyooqIijR07Vp07d9apU6ckScHBwdq6dav+9re/qXnz5lq+fLmuv/56JVVwafTDhw9rwIABuvXWWzVx4sQK3dYoXg8kkrRkyRK1atVKU6ZM0fTp03XTTTdp27ZtrsNbAAAAQHmUZoKICGnuXCk+3vOP2b59e0nSF1984RrLzMxU165dlZqaesnbr169WsePH9eGDRs0btw4xcfHa//+/W77zJ49W/v379eQIUM0f/58ffTRR9q1a5e2bNkiSUpKStKcOXPUp08fTZs2Tdu3b1eTJk3OmxtyMfn5+erXr5+uuuoqLVu2zLTvCDTlixHr1aunpWdPYgQAAAAqwGJxHh0JD3fOIRk50ntzSFq0aKH77rtPEyZMkN1uV6NGjfTSSy+pWbNm6tGjxyVvX6dOHRUVFWnhwoWKjo7WwoULtXLlSsXFxbn2ycjI0NKlS/Xiiy+qdu3aevvtt2W1WtW4cWNJUlBQkKZOnarAwEB16tRJ3333nQ4ePKgHHnig3M9j/Pjx+ve//6233npLBw4c0IEDB1z1RXnxVFlTAgkAAGUaNsz5rezMGQFwAWYGkbMtWbJEU6ZM0cSJE1VcXKxu3brpnXfeKdcKUwMHDtTWrVtdgSIxMVFPP/205s6dq2PHjqlGjRp65ZVX9OSTT2rMmDE6evSomjVrphUrVqhp06aSpLi4OC1YsEAvv/yypkyZoquvvlrDhw/XpEmTyv0c3nvvPTkcDo0YMcJtfOjQoVrkxS+oteTn5/vON7Rchr179yo2Nla7d+9W69aty9zHbrfrxIkTLAVoEPppPHpqLPppPHpqLPppPHpqLCP6WfrX9tIP0Jfr/fel++8/cz0iwtwgcjkcDofsdrusVqtpp0UZpTy/1z179qhNmzZKTU1Vq1atLnmfHCEBAACAz7rmGuelPwYRlA+BBAAAAD6rZ09p82apXTuCSGVFIAEAAIDPslikLl3MrgKeZMqyvwAAAAAgEUgAAAAAmIhAAgAAAMA0BBIAAAAApiGQAAAAADANgQQAAACAaQgkAAAAAExDIAEAAAA8IDMzUxaLRZmZmWaXckGHDx/W1KlTdd999+mJJ54wpVYCCQAAAPyKw+FQ8n+T5XA4zC7Frx05ckSxsbHatm2bWrdurY0bN6pjx446fPiwV+sgkAAAAMCvLNu1TF0XdtXyb5abXYpfe+6559SiRQt99tlneu6555ScnKzi4mK9++67Xq2DQAIAAAC/snLPSrdLXJ4+ffpo7ty5slgskqTq1aurZs2aKiws9GodBBIAAAD4jeOFx7U+Y70k6dP0T3W88LgpdRQWFmrChAmqW7euatasqX79+ikjI6Pct09PT9dtt92mGjVqKDw8XKNGjVJBQYHb/Y8bN04NGjSQzWZTly5d9NVXX7ndx+rVq9W2bVtVr15djRs31ssvv+zaZrfbVVxcXOZPSUmJJKlfv35q3bq16zbvvvuufvzxR919992X2ZXLQyABAACAz7KX2NVzcU9d+9q1uva1axX9RrSKSookSUUlRYp+I9q1rdeSXipxlHilriFDhmjx4sWaPXu2Vq1apWPHjqlPnz4qKiq65G0dDof69eunw4cPa/Xq1XrzzTf18ccf65VXXnHtM2PGDL399tt65ZVXtHbtWjVs2FB33XWXa95Menq67r//fsXHx+vTTz/VE088ocmTJ2vdunWSpJ49eyooKKjMn+HDh7vVk5KSori4OD3wwAP629/+puuuu87ATl1aoFcfDQAAAKig0yWnlXU8q8xtOfk5rv9uXLOx8wO7xbP1fP/993rvvfe0ePFiDRkyRJJUt25dTZs2TdnZ2WrUqNFFb3/y5EmNHz9eiYmJuu6661RSUqIlS5Zoy5Ytrn0yMzN17bXXatCgQbJYLIqJidG2bdtUXFysoKAg/fDDD7Lb7Ro6dKg6d+6srl27qmXLlmratKkkacGCBcrLyyvz8WvVquV2vWHDhurZs6cyMjL0+uuv67bbblNoaOiVtKhCCCQAAADwWdYAqzYM2aCnNz6t2ZtnyyKLHDqzulbp9Ulxk/RC4guyBlg9XtPOnTslSQkJCa6xmJgYrVq1qly3t9lsuueee7R48WIlJSVp27Ztys3Ndbu/4cOH6/3331fbtm3VrVs3xcXFqX///goKCpIk3XzzzerQoYP69u2r3r17KzY2Vv3791eTJk0kSc2bNy/384mKitILL7yghx9+WC1bttScOXM0derUct/+SnHKFgAAAHxasDVYs26Zpek9pruFEUlyyKEZPWdoZq+ZCrYGe6We0tOmSieDl44lJyeXa8ncrKwstWrVSmvXrtWtt96qNWvWnBcAEhISlJ6erokTJ6qoqEhjx45V586dderUKUlScHCwtm7dqr/97W9q3ry5li9fruuvv15JSUnlfh4//PCD27yVBg0aqGPHjtq3b1+578MIBBIAAAD4hV05u8oezy573FPat28vSfriiy9cY5mZmeratatSU1MvefvVq1fr+PHj2rBhg8aNG6f4+Hjt37/fbZ/Zs2dr//79GjJkiObPn6+PPvpIu3btcp3WlZSUpDlz5qhPnz6aNm2atm/friZNmmjhwoXlfh7x8fF64403XNeLi4uVkZGhqKioct+HEThlCwAAAD7vVPEpffjdh5KkwIBAPdj2QS3btUzFJcX68PsPdar4lK4KvMortbRo0UL33XefJkyYILvdrkaNGumll15Ss2bN1KNHj0vevk6dOioqKtLChQsVHR2thQsXauXKlYqLi3Ptk5GRoaVLl+rFF19U7dq19fbbb8tqtapx48aSpKCgIE2dOlWBgYHq1KmTvvvuOx08eFAPPPBAuZ/HhAkT9OSTT8pisejGG2/UO++8o+PHj5836d3TCCQAAADweft+2qf8onxF14rWu/e+qw71O+iRTo9owKoBSs9N176f9ql9/fZeq2fJkiWaMmWKJk6cqOLiYnXr1k3vvPOObDbbJW87cOBAbd261RUoEhMT9fTTT2vu3Lk6duyYatSooVdeeUVPPvmkxowZo6NHj6pZs2ZasWKFa9J6XFycFixYoJdffllTpkzR1VdfreHDh2vSpEnlfg6PPvqo7Ha73njjDf3000/q3LmzPv/8c9djeIslPz/fcendfNfevXsVGxur3bt3u62jfDa73a4TJ04oLCxMVqvnJzpVdvTTePTUWPTTePTUWPTTePTUWEb088CBA5Jk2IfbEkeJNv5no25qdJNCg8+sAJV3Ok9bf9iqHk16KMDim7MRHA6H7Ha7rFar27wTf1Se3+uePXvUpk0bpaamqlWrVpe8T46QAAAAwOcFWALUq2mv88ZDg0PLHIf/8M0YCeCKpSlNgzRIbdVWgzRIaUozuyQAAIDzcIQEqITSlKYu6qICOZfy+0bfaK3Waou2KEYxJlcHAABwBkdIgEpopma6wkipAhVopmaaVBEAAEDZCCRAJbRHe8oc36u9Xq4EAADg4ggkQCXUWmWvONdKl17pAgAAwJsIJEAlNFmTFaIQt7EQhWiyJptUEQAAQNkIJEAlFKMYbdEWDdRAtVVbDdRAJrQDAACfxCpbQCUVoxit0AqzywAAALgojpAAAAAAHpCZmSmL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VOefLtRT3kcr5ujRoxo6dKgiIiJUs2ZN9enTRwcPHnRt5zVaMZfqJ6/PsgWaXYAnFRUVaeTIkfr222/L3J6WlqYRI0Zo6NChrjGbzeat8vzOpfr5f//3f0pOTtbs2bNVUlKihx56SA0bNlTnzp29XKl/ys7O1uHDh/X3v/9d9erVc41HRkaaWJX/+dOf/qSnnnpKU6ZMUYcOHTRx4kTZbDY9/vjjZpfml9LS0tSxY0e9/vrrbuPVqlUzpyA/9N1332n48OGqXr262/jBgwd15513ql27dlq2bJlWrVqle+65RykpKQoKCjKpWv9woZ7yPlpxgwcP1vfff6/JkycrMDBQs2bN0m9/+1slJyfzGr0MF+snr88Lq7SB5NSpU7r33nt1/PjxC+6TlpamYcOGqUOHDl6szD9dqp9ff/21PvroIy1ZskS/+c1vJDn/sZ01axZHSsopLS1NYWFh6t27tywWi9nl+KXTp09rxowZGjFihKZMmSJJCgkJ0aBBgzRu3DgFBlbatzyP2bVrl2JjY3mfvEzbt29X//791aRJE/30009u21577TUFBQXp/fffl81mU48ePdS2bVt9+OGHuueee0yq2PddrKe8j1bMxo0btX37dqWmpqpx48aSpLCwMI0ePVqZmZl6/fXXeY1WwKX6+f333/P6vIBKe8pWdna2ateurU8++aTM7YcOHVJOTo46duzo5cr806X6uXHjRlWvXl133nmna6xfv3764osvZLfbvVWmX0tLS1P79u15k7oC//73v/XLL79owIABrrFu3bpJcoZmVNzOnTsJI1cgOTlZ06dP18iRI8/b9vnnn6tfv36uI/NWq1V9+/bV559/7u0y/crFesr7aMV07NhRmzZtcn14lqRatWpJcv6Bh9doxVyqn7w+L8xvA0lJSYmKi4vL/LHb7YqMjNTixYsVGhpa5u137NihwMBADRkyRHXq1FGLFi30wgsvqKioyMvPxDdcaT8PHTqkFi1auB3CjYyMVEFBgf73v/9562n4tEv1eMeOHcrKylLLli1Vu3ZtJSQk6LPPPjO7bL9y6NAhSTrvvPKGDRsqPT3djJL82rFjx5SRkaH58+erfv36atiwoYYPH67Dhw+bXZrfePTRRzV48OAytx06dOi812pkZCSv1Uu4WE95H62YGjVqqGXLlm5j69evV506ddS8eXNeoxV0qX7y+rwwvw0kDz/8sGrUqFHmz+23366AgIs/te3bt6tatWq644479P7772vUqFH64x//qBkzZnjpGfiWK+1nQUGBatas6TYWEhIiSTpy5IinyvYrl+rx9u3bVaNGDU2bNk3vvvuu6tWrp/vuu0/fffed2aX7jYKCAlmtVoWFhbmNh4SE8Dq8DP/+97/lcDjUvn17LVu2TLNmzdIXX3xxwQ+DON/F3jsv9L7Ja/XiLtZT3kevzH/+8x8tW7ZMY8eOVUBAAK/RK3RuP3l9XpjfnlD99NNPa8yYMWVuu9Bf8c82YsQI/fa3v1WzZs0kSYmJiTp58qTefvttPfXUU5f8AF7ZXGk/q1WrJqvV6jYWHBwsyfmPLi7d4+PHj6t58+auD9OJiYlq27atFi5cqJkzZ3qzVL9VrVq1MueJBAcHsyrUZejQoYM2b96smJgY11jDhg3Vr18/7d69u8wVjlB+F3rf5LV6+VauXMn76GUqKSnRww8/rIYNG7r+reI1evnK6ievzwvz20ASGRl5RasSNGjQ4Lyxm266SbNmzdL//vc/NWrU6ErK8ztX2s+6desqJSXFbSw3N1eSzlsFpaqqaI8DAwMVGxurXbt2ebCqyqVu3boqLCzU0aNHVbt2bdf4zz//zOvwMtSoUcMtjEhSly5dJDknuxNIrkzdunVdpxmWys3N5bV6Bdq3b+92nffR8nv11Ve1ZcsWrV+/3vUa5DV6+crqJ6/PC6tahwHOsn37dmVnZ7uN/fzzz5JE8r8MsbGx2r9/v44ePeoa27FjhySpfv36ZpXlN/Lz85WUlHTeeG5urgoLC71fkJ+KiYlRcHCwtm7d6ho7ceKE9u/fz+vwMmRmZmrPnj1uY6Xvk7wur1ynTp3cXquScxEBXquXh/fRy5eUlKRp06bp2Wef1U033eQa5zV6ecrqJ6/Pi6uygWT8+PGaP3++29iKFStUp04dNW3a1KSq/FdiYqJCQ0M1d+5cSZLD4dBf//pXtWrVSuHh4SZX5/syMzPVr18/t4mCBw8e1ObNmxUbG2tiZf6lRo0a6tGjh+bMmeNa3W3+/PlyOByu1bZQfvPnz9f48ePdxpYvXy5JvC4NcPfdd2vdunXavXu3JOf/8x9//LESExNNrsw/8T56efbt26cHH3xQffv21YQJE9y28RqtuAv1k9fnxfntKVtX6qGHHtIjjzwiq9Wqxo0b6x//+Ic+++wzvfbaa1Vu/ogRgoKC9Mwzz2jChAnat2+ffv75Z23evFnvvvuu2aX5hdatWys+Pl4DBgzQ6NGjdfr0ac2dO1c2m01jx441uzy/8tRTT6lXr17q3r27oqKi9MEHH+j3v/+96tata3Zpfmfo0KF68803NWLECPXo0UNpaWn6y1/+onvuuYfTtQxwxx13qEOHDurbt6/69u2rDRs2qE6dOvrd735ndml+iffRiisqKtKDDz4oi8Wi0aNHu85skKTGjRvzGq2gS/WT1+eFVdlAMnjwYP3yyy964403dPToUbVq1UqrV69W7969zS7Nb40aNUoRERGaN2+eLBaL3n//fd12221ml+U3lixZoscff1xTpkxRcHCwevXqpenTp3NovILat2+vTZs2adq0afrPf/6jadOm6dFHHzW7LL90/fXXa+XKlZo6dapWr16tRo0a6aWXXtLo0aPNLq1SCAwM1Icffqjp06dr48aNSkhI0Isvvqirr77a7NL8Fu+jFbNnzx59++23knTev9d//etfNXjwYF6jFXCpfvL6vDBLfn6+w+wiAAAAAFRNnJsEAAAAwDQEEgAAAACmIZAAAAAAMA2BBAAAAIBpCCQAAAAATEMgAQAAAGAaAgkAAAAA0xBIAAAAAJiGQAIAAADANAQSAAAAAKYhkAAAAAAwDYEEAAAAgGkIJAAAAABM8/+pNtJR93q2lwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 960x720 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "import matplotlib\n",
    "\n",
    "\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] #指定默认字体 SimHei为黑体\n",
    "plt.rcParams['axes.unicode_minus']=False   #用来正常显示负号\n",
    "\n",
    "colors = ['red', 'purple', 'blue', 'green', 'lime']\n",
    "shapes = ['+', 'o', '>', '*', '.']\n",
    "\n",
    "\n",
    "# create 5 different list containing 5 classes of points\n",
    "upper_list = []\n",
    "for i in range(k):\n",
    "    new_list = []\n",
    "    upper_list.append(new_list)\n",
    "# assign each point into its corresponding class\n",
    "data_with_lab = zip(data, label)\n",
    "\n",
    "\n",
    "for dat, lab in data_with_lab:\n",
    "    for i in range(k): \n",
    "        if lab == i:\n",
    "            upper_list[i].append(dat.tolist())\n",
    "            \n",
    "fig, ax = plt.subplots(1,1,facecolor='whitesmoke',edgecolor='grey',\n",
    "                       dpi=120,figsize=(8,6))\n",
    "#fig.suptitle(\"knn results visualization\",fontsize=18, color='red')\n",
    "ax.set_title('knn with groups')\n",
    "\n",
    "for i in range(k):\n",
    "    ax.scatter(np.array(upper_list[i])[:,0],\n",
    "               np.array(upper_list[i])[:,1],\n",
    "               color=colors[i], \n",
    "               marker=shapes[i],\n",
    "               label=\"class-\"+str(i))\n",
    "\n",
    "# plot the unassigned point\n",
    "ax.plot(target[0],target[1],color='black',marker='<',label=\"untold\")\n",
    "ax.text(target[0]-1.8,target[1]+1.2,\n",
    "        'class-'+str(target_lab[0]),\n",
    "        fontsize=8)\n",
    "\n",
    "ax.legend()\n",
    "ax.grid(alpha=0.2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00b46722",
   "metadata": {},
   "source": [
    "## 总结\n",
    "1. np.array() 或是 np.asarray() 能够将list转换为ndarray，便于操作\n",
    "2. python中的zip是位置上的一对一重组，并且组合后成为tuple，其中的二者仍旧保持着独立的关系，能够使用for进行拆包\n",
    "3. pyplot之中rcParam属性\n",
    "4. 使用上位list嵌套下位list的方法能够按照需求建立k个list进行元素的放置"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae73e58a",
   "metadata": {},
   "source": [
    "## sklearn knn\n",
    "1. sklearn.neighbors KNeighborsClassifier\n",
    "    > classifier  算法中有两个需要指定方法的部分 <br>\n",
    "    > 首先是如何从所有最近点中选举出未知点的标签，体现在weights参数上 <br>\n",
    "    > 其次是如何选举出最近的k个点，体现在algorithm以及leaf_size参数对上 <br>\n",
    "    > 最后是如何计算距离， 体现在metric以及metrix_param参数上 <br>\n",
    "    > n_neighbors参数是必须的 <br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 259,
   "id": "eb0aebe7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])"
      ]
     },
     "execution_count": 259,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "\n",
    "iris = load_iris()\n",
    "iris.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 261,
   "id": "31cc56e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  0 13]\n",
      " [ 0  0  8]\n",
      " [ 0  0  9]]\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.00      0.00      0.00        13\n",
      "           1       0.00      0.00      0.00         8\n",
      "           2       0.30      1.00      0.46         9\n",
      "\n",
      "    accuracy                           0.30        30\n",
      "   macro avg       0.10      0.33      0.15        30\n",
      "weighted avg       0.09      0.30      0.14        30\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/collinsliu/opt/anaconda3/lib/python3.9/site-packages/sklearn/metrics/_classification.py:1318: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, msg_start, len(result))\n",
      "/Users/collinsliu/opt/anaconda3/lib/python3.9/site-packages/sklearn/metrics/_classification.py:1318: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, msg_start, len(result))\n",
      "/Users/collinsliu/opt/anaconda3/lib/python3.9/site-packages/sklearn/metrics/_classification.py:1318: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, msg_start, len(result))\n"
     ]
    }
   ],
   "source": [
    "data_iris = iris.data\n",
    "label_iris = iris.target\n",
    "properties_iris = iris.feature_names\n",
    "names_iris = iris.target_names\n",
    "\n",
    "# split raw data and label into train and test set\n",
    "data_iris_train, data_iris_test, label_iris_train, label_iris_test  \\\n",
    "    = train_test_split(data_iris, label_iris, test_size=0.2)\n",
    "# scale feature into standard normalized pattern\n",
    "scaler = StandardScaler()\n",
    "scaler.fit(data_iris)\n",
    "data_iris_train_sca = scaler.transform(data_iris_train)\n",
    "data_iris_test_sca = scaler.transform(data_iris_test)\n",
    "# initiate KNN learning module\n",
    "classifier = KNeighborsClassifier(n_neighbors=5)\n",
    "# feed triaining data into\n",
    "classifier.fit(data_iris_train_sca, label_iris_train)\n",
    "# predict test data and estimate efficiency of module\n",
    "label_iris_pred = classifier.predict(data_iris_test)\n",
    "print(confusion_matrix(label_iris_test,label_iris_pred))\n",
    "print(classification_report(label_iris_test,label_iris_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 265,
   "id": "34a11f17",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0.03333333333333333,\n",
       " 0.03333333333333333,\n",
       " 0.03333333333333333,\n",
       " 0.06666666666666667,\n",
       " 0.03333333333333333,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.03333333333333333,\n",
       " 0.1,\n",
       " 0.03333333333333333,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.03333333333333333,\n",
       " 0.03333333333333333,\n",
       " 0.03333333333333333,\n",
       " 0.0,\n",
       " 0.03333333333333333,\n",
       " 0.03333333333333333,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.1,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.1,\n",
       " 0.1,\n",
       " 0.1,\n",
       " 0.06666666666666667,\n",
       " 0.06666666666666667,\n",
       " 0.1,\n",
       " 0.13333333333333333,\n",
       " 0.1,\n",
       " 0.13333333333333333,\n",
       " 0.13333333333333333]"
      ]
     },
     "execution_count": 265,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# evaluate error rate with the expansion of k\n",
    "error = []\n",
    "for i in range(41):\n",
    "    knn_classifier = KNeighborsClassifier(n_neighbors=i+1)\n",
    "    knn_classifier.fit(data_iris_train_sca, label_iris_train)\n",
    "    label_iris_pred_k = knn_classifier.predict(data_iris_test_sca)\n",
    "    error.append(np.mean(label_iris_pred_k != label_iris_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b609d400",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
